package util;

import com.alibaba.druid.pool.DruidDataSourceFactory;

import javax.sql.DataSource;
import java.io.IOException;
import java.io.InputStream;
import java.lang.reflect.Field;
import java.sql.*;
//import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;
import java.util.Properties;

public class DBUtil {
    //获取数据源
    public static DataSource getDruidDataSource() {
        DataSource dataSource = null;
        Properties pro = new Properties();
        InputStream stream = DBUtil.class.getClassLoader().getResourceAsStream("druid.properties");
        try {
            //加载druid.properties配置信息
            pro.load(stream);
        } catch (IOException e) {
            e.printStackTrace();
        }
        //创建dataSource
        try {
            dataSource = DruidDataSourceFactory.createDataSource(pro);
        } catch (Exception e) {
            e.printStackTrace();
        }

        return dataSource;
    }
    //获取连接
    public static Connection getConn() {
        DataSource dataSource = DBUtil.getDruidDataSource();
        Connection connection = null;
        try {
            connection = dataSource.getConnection();
        } catch (SQLException e) {
            e.printStackTrace();
        }
        return connection;
    }

    //释放资源方法
    public static void closeAll(ResultSet rs, PreparedStatement pst, Connection conn) {
        try {
            if (rs != null) {
                rs.close();
            }
            if (pst != null) {
                pst.close();
            }
            if (conn != null) {
                conn.close();
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    //增删改方法
    public static int executeUpdate(String sql, Object... objects) {
        //1.获取链接
        Connection conn = DBUtil.getConn();
        PreparedStatement pst = null;
        int row = -1;
        try {
            //2.创建一个PreparedStatement对象
            pst = conn.prepareStatement(sql);
            //3.给参数赋值
            for (int i = 0; i < objects.length; i++) {
                pst.setObject(i + 1, objects[i]);
            }
            //4.执行sql,获取返回结果
            row = pst.executeUpdate();
        } catch (SQLException e) {
            e.printStackTrace();
        } finally {
            DBUtil.closeAll(null, pst, conn);
        }
        return row;
    }
    //查询的方法
    public static <T> List<T> executeQuery(Class<T> clazz, String sql, Object... objects) {
        List<T> list = new ArrayList<>();
        Connection conn = DBUtil.getConn();
        PreparedStatement pst = null;
        ResultSet rs = null;
        try {
            // 获取pst
            pst = conn.prepareStatement(sql);
            // 给参数赋值
            for (int i = 0; i < objects.length; i++) {
                pst.setObject(i + 1, objects[i]);
            }
            // 执行查询，处理返回结果
            rs = pst.executeQuery();
            // 获取元数据
            ResultSetMetaData rmd = rs.getMetaData();
            // 获取列数量
            int count = rmd.getColumnCount();
            while (rs.next()) {
                try {
                    T t = clazz.newInstance();
                    for (int i = 0; i < count; i++) {
                        String label = rmd.getColumnLabel(i + 1);
                        Object obj = rs.getObject(label);
                        // 获取属性并给属性赋值
                        Field field = clazz.getDeclaredField(label);

                        //解决 mysql8.0 日期转化问题
//                        if (obj.getClass().toString().equals("class java.time.LocalDateTime")){
//                            obj=Timestamp.valueOf((LocalDateTime) obj);
//                        }

                        field.setAccessible(true);
                        field.set(t, obj);
                    }
                    list.add(t);
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        } catch (SQLException e) {
            e.printStackTrace();
        } finally {
            DBUtil.closeAll(rs, pst, conn);
        }
        return list;
    }
    //测试获取连接
    public static void main(String[] args) {
        System.out.println(DBUtil.getConn());
    }
}
